iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 19
1

ASP.NET 框架中有提供 Entity Framework 作為跟資料庫溝通用的 ORM 框架,將資料表轉成 POCO 類別,方便開發人員操作資料庫,用物件導向的概念來取代傳統 ADO.NET 的操作方式。在 ASP.NET Core 框架中也有提供 Entity Framework Core (EF Core) 來延續這個優良的傳統XD

使用 EF Core 的方式大致可分為兩種:

  1. Code First: 先建立 POCO 類別,再用 Migration 的方式建立或更新資料庫。
  2. Database First: 先建立資料庫,再產生對應的 POCO 類別。

今天會先介紹用 Code First 的方式來操作資料庫。

安裝依賴套件

為了方便說明,我們今天會操作 Sqlite 資料庫。可以參考 Database Providers 找看看官方或第三方提供的資料庫整合介面。開始前要先加入相關的依賴。

套件管理員主控台

Install-Package Microsoft.EntityFrameworkCore -Version 2.1.4
Install-Package Microsoft.EntityFrameworkCore.Sqlite -Version 2.1.4
Install-Package Microsoft.EntityFrameworkCore.Sqlite.Design -Version 1.1.6

dotnet CLI

dotnet add package Microsoft.EntityFrameworkCore --version 2.1.4
dotnet add package Microsoft.EntityFrameworkCore.Sqlite --version 2.1.4
dotnet add package Microsoft.EntityFrameworkCore.Sqlite.Design --version 1.1.6

建立模型

這邊用最常看到的 Todo 作為範例。先建立資料模型 TodoModel,在執行 Migration 時這個類別會被轉換成資料表,並利用 System.ComponentModel.DataAnnotations 命名空間中的 annotation 來為屬性(欄位)加上額外條件:

public class TodoModel
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Required]
    public string Title { get; set; }

    [Required]
    public DateTime CreatedAt { get; set; }

    public bool Completed { get; set; }
}

再建立一個繼承 DbContext 的類別來跟資料庫溝通,並把資料模型作為 DbSet<TEntity> 屬性:

public class IronmanContext : DbContext
{
    public IronmanContext(DbContextOptions<IronmanContext> options) : base(options)
    {
    }

    // 這邊的屬性名稱會作為實際的資料表名稱
    public DbSet<TodoModel> Todo { get; set; }
}

資料庫來源

在設定檔 appsettings.json 中加入資料庫連線字串,指定資料庫來源:

{
    "ConnectionStrings": {
        "Sqlite": "Data Source=./todo.db"
    } 
}

並在 Startup.ConfigureServices 中,把 DbContext 加入服務容器中,同時指定連線字串:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<IronmanContext>(optionsBuilder =>
    {
        optionsBuilder.UseSqlite(_config.GetConnectionString("Sqlite"));
    });
}

資料庫移轉 (Migration)

在 VS2017 中,建議使用 EF Core Tools 來進行移轉。在套件管理主控台中執行以下命令:

Install-Package Microsoft.EntityFrameworkCore.Tools -Version 2.1.4
Add-Migration IronmanMigration
Update-Database

https://ithelp.ithome.com.tw/upload/images/20181102/20107875dnsygX5z3Z.png

或者在 dotnet CLI 中執行:

dotnet ef migrations add IronmanMigration
dotnet ef database update

執行 Add-Migrationdotnet ef migrations add 時,會在專案目錄中的 Migrations 目錄新增三個檔案,其中檔案名稱開頭的是執行移轉時的時間戳記,可以用來排序後方便觀察資料庫的變化。:

  • 20181102143845_IronmanMigration.cs:Migration 時的主要作業。
  • 20181102143845_IronmanMigration.Designer.cs:Migration Metadata。
  • IronmanContextModelSnapshot.cs:當前的模型快照,用來判斷下一次執行移轉時要變更的項目。

而執行 Update-Databasedotnet ef database update 時,會建立資料庫並套用移轉。最後我們就會得到一個 todo.dbSqlite 檔案。
https://ithelp.ithome.com.tw/upload/images/20181102/20107875E5aE9W2k1p.png

CRUD

因為我們已經把繼承 DbContext 的物件加到服務容器中了,在應用程式中就可以直接注入來使用:

public class EntityFrameworkController : Controller
{
    private readonly IronmanContext _context;

    public EntityFrameworkController(IronmanContext context)
    {
        _context = context;
    }
}
  • 新增
public IActionResult Create()
{
    _context.Todo.Add(new TodoModel
    {
        Title = "EF Core Code First",
        CreatedAt = DateTime.Now,
        Completed = false
    });

    _context.SaveChanges();

    return new EmptyResult();
}

https://ithelp.ithome.com.tw/upload/images/20181102/20107875M1hEINe8cd.png

  • 讀取
public IActionResult Read()
{
    return Json(_context.Todo.ToList());
}

https://ithelp.ithome.com.tw/upload/images/20181102/20107875krfyJ2ayFx.png

  • 修改
public IActionResult Update()
{
    var todo = _context.Todo.First(m => m.Id == 1);
    todo.Completed = true;

    _context.SaveChanges();

    return new EmptyResult();
}

https://ithelp.ithome.com.tw/upload/images/20181102/20107875errDlOQAAI.png

  • 刪除
public IActionResult Delete()
{
    var todo = _context.Todo.First(m => m.Id == 1);

    _context.Remove(todo);
    _context.SaveChanges();

    return new EmptyResult();
}

https://ithelp.ithome.com.tw/upload/images/20181102/20107875MlGt1jpwUc.png


可能對程式設計師來說,先建立資料模型是比較直覺的方式。但個人經驗是在稍微有規模的專案中,資料表的設計比較複雜時,會先有 SA 或 SD 設計好資料表,再由 PG 接手開發,這就要採用明天會說明的 Database First 方式了。(但最近看越來越多人採 Code First 方式開發了,可能是我還不習慣吧QQ)

參考資料


上一篇
Caching 快取
下一篇
Entity Framework Core - 2/2
系列文
.Net Core 網站開發 10131
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言